#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <inttypes.h>
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "wifi_device.h"
#include "wifi_hotspot_config.h"
#include "iot_gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define KEY_GPIO_PIN (34) // 替换为实际的KEY GPIO引脚
#define LED1 (5)
#define LED2 (2)
#define TIMEOUT_MS 3000000 // 超时时间，单位毫秒

static WifiErrorCode wifi_error;
static WifiEvent g_wifiEventHandler = {0};

// 事件处理函数
static void OnHotspotStaJoinHandler(StationInfo *info)
{
    (void)info;
    printf("STA joined AP\n");
}

static void OnHotspotStaLeaveHandler(StationInfo *info)
{
    (void)info;
    printf("STA left AP\n");
}

static void OnHotspotStateChangedHandler(int state)
{
    printf("Hotspot state changed: state = %d\n", state);
}

// Wi-Fi初始化
static void WiFiInit(void)
{
    printf("<-- Wi-Fi Init -->\n");
    g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler;
    g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler;
    g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler;
    wifi_error = RegisterWifiEvent(&g_wifiEventHandler);
    if (wifi_error != WIFI_SUCCESS)
    {
        printf("Register Wi-Fi event failed! Error code: %d\n", wifi_error);
    }
    else
    {
        printf("Register Wi-Fi event succeeded!\n");
    }
}

// 初始化Wi-Fi AP模式
static void InitWifiAp(void)
{
    static flag_firsttime = true;
    printf("Initializing Wi-Fi AP mode...\n");

    const char *sn = getDeviceSN();
    if (sn)
    {
        printf("++++++++++++++++getSnDemo SN is [%s]++[]\n", sn);
    }
    char ssid[16]; // 确保数组足够大以存储新的SSID

    // 使用强制类型转换int数据的方法判断是否为0
    if (sn && (intptr_t)sn != 0)
    {
        size_t len = strlen(sn);
        snprintf(ssid, sizeof(ssid), "IC204%s", sn + len - 4);
    }
    else
    {
        snprintf(ssid, sizeof(ssid), "IC2040000");
    }
    ssid[strlen(ssid)] = '\0';
    printf("++++++++++++++++wifiAPName is [%s]\n", ssid);
    HotspotConfig ap_config =
        {
            .ssid = "IC2040000",
            // .ssid = ssid,
            .preSharedKey = "123456789",
            .securityType = WIFI_SEC_TYPE_PSK,
        };
    if (SetHotspotConfig(&ap_config) != WIFI_SUCCESS)
    {
        printf("Set hotspot config failed, error code: %d\n", wifi_error);
        return;
    }
    // added 12.23 for errcode0x103
    if (flag_firsttime)
    {
        printf("flag_firsttime\n");
        flag_firsttime = false;
        esp_event_loop_delete_default();
    }
    // added 12.23 for errcode0x103
    int result = EnableHotspot();
    if (result != WIFI_SUCCESS)
    {
        printf("Enable hotspot failed, error code: %d\n", wifi_error);
        printf("Enable hotspot failed, error codev002: %d\n", result);
        return;
    }
    printf("Wi-Fi AP mode enabled\n");
}

// 禁用Wi-Fi AP模式
static void DisableWifiAp(void)
{
    printf("Disabling Wi-Fi AP mode...\n");
    if (DisableHotspot() != WIFI_SUCCESS)
    {
        printf("Disable hotspot failed, error code: %d\n", wifi_error);
        return;
    }
    printf("Wi-Fi AP mode disabled\n");
}

// 检查KEY是否按下，并根据状态开启或关闭Wi-Fi AP模式
static void CheckKeyAndToggleWifiAp(IotGpioValue *inputValuePtr, uint32_t *lastKeyPressedTime)
{
    static bool wifiApEnabled = false;
    static IotGpioValue last_inputValue = 1;
    IotGpioValue inputValue;
    IotGpioValue outputValue;
    IoTGpioInit(KEY_GPIO_PIN);
    IoTGpioInit(22);

    IoTGpioInit(LED1);
    IoTGpioInit(LED2);

    IoTGpioSetDir(LED1, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(LED2, IOT_GPIO_DIR_OUT);

    IoTGpioSetDir(KEY_GPIO_PIN, IOT_GPIO_DIR_IN);
    IoTGpioSetDir(22, IOT_GPIO_DIR_OUT);
    IoTGpioGetInputVal(KEY_GPIO_PIN, &inputValue);
    IoTGpioGetInputVal(22, &outputValue);

    if (inputValue == 0 && last_inputValue != 0)
    // 从原先的【高电平触发】修改为【上升沿触发】，避免一直按下一直被触发
    // TODO：最好做个消抖
    { // 假设按键按下为低电平，初始化为高电平
        if (!wifiApEnabled)
        {
            // only_once = true;
            printf("KEY pressed, enabling Wi-Fi AP mode...\n");
            *lastKeyPressedTime = osKernelGetSysTimerCount();                  // 记录按键按下的时间
            printf("00000000 lastKeyPressedTime = %u\n", *lastKeyPressedTime); // 打印当前时间和最后按键时间
            InitWifiAp();
            wifiApEnabled = !wifiApEnabled;
        }
        else
        {
            printf("WIFI enabled already!!!\n");
        }
    }
    else
    {
        if (wifiApEnabled)
        {
            uint32_t currentTime = osKernelGetSysTimerCount();
            if ((currentTime - *lastKeyPressedTime) > TIMEOUT_MS)
            {
                printf("1111111 currentTime = %u lastKeyPressedTime = %u\n", currentTime, *lastKeyPressedTime); // 打印当前时间和最后按键时间
                printf("KEY not pressed for 30 seconds, disabling Wi-Fi AP mode...\n");
                DisableWifiAp();
                printf("1111111 DisableWifiAp success\n");
                wifiApEnabled = !wifiApEnabled;
            }
        }
    }

    if (wifiApEnabled)
    {
        IoTGpioSetOutputVal(LED1, 1);
        IoTGpioSetOutputVal(LED2, 0);
    }
    else
    {
        IoTGpioSetOutputVal(LED1, 0);
        IoTGpioSetOutputVal(LED2, 1);
    }

    last_inputValue = inputValue;
    // printf("CheckKeyAndToggleWifiAp X\n");
}

void print_stack_usage()
{
    TaskHandle_t xHandle = xTaskGetHandle("WIFI_AP_TASK");
    UBaseType_t uxStackHighWaterMark = uxTaskGetStackHighWaterMark(xHandle);
    printf("Stack High Water Mark: %u\n", uxStackHighWaterMark);
    UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
    printf("Stack Totalnum: %u\n", uxArraySize);
}

void print_every_task()
{
    UBaseType_t uxArraySize, x;
    uint32_t ulTotalRunTime;
    TaskStatus_t *pxTaskStatusArray;

    // 确定任务的数量
    uxArraySize = uxTaskGetNumberOfTasks();

    // 分配足够的空间来存储每个任务的状态信息
    pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc(uxArraySize * sizeof(TaskStatus_t));

    if (pxTaskStatusArray != NULL)
    {
        // 获取所有任务的状态信息
        uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &ulTotalRunTime);

        for (x = 0; x < uxArraySize; x++)
        {
            // 打印任务的状态信息，例如任务名称和状态
            printf("Task Name: %s, State: %d\n", pxTaskStatusArray[x].pcTaskName, pxTaskStatusArray[x].eCurrentState);
        }

        // 释放之前分配的内存
        vPortFree(pxTaskStatusArray);
    }
}

void WifiApTask(void)
{
    printf("WifiApTask E\n");
    IotGpioValue inputValue;
    bool wifiApEnabled = false;
    uint32_t lastKeyPressedTime = 0;
    printf("Wi-Fi AP mode demo start!\n");
    WiFiInit();
    // osDelay(15000); // 稍微延时，减少CPU占用

    while (1)
    {
        CheckKeyAndToggleWifiAp(&inputValue, &lastKeyPressedTime);
        osDelay(3000); // 稍微延时，减少CPU占用
    }
    printf("WifiApTask X\n");
}

void WifiApDemo(void)
{
    printf("WifiApDemo E\n");
    osThreadAttr_t attr;
    attr.name = "WIFI_AP_TASK";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 25;

    if (osThreadNew((osThreadFunc_t)WifiApTask, NULL, &attr) == NULL)
    {
        printf("Failed to create thread!\n");
    }
    printf("WifiApDemo X\n");
}

APP_FEATURE_INIT(WifiApDemo);